package com.dzl.moive.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dzl.admin.pojo.dto.SendMsgDto;
import com.dzl.base.service.BaseServiceImpl;
import com.dzl.card.pojo.WelfareCardSecret;
import com.dzl.card.pojo.vo.WelfareUserCardSecretVo;
import com.dzl.card.service.WelfareCardSecretService;
import com.dzl.config.ApplicationConfiguration;
import com.dzl.config.database.Master;
import com.dzl.config.exception.CommonException;
import com.dzl.constant.CommonConstants;
import com.dzl.constant.OperationConstant;
import com.dzl.enterprise.pojo.WelfareEnterprise;
import com.dzl.enterprise.service.WelfareEnterpriseService;
import com.dzl.fee.pojo.vo.WelfareFeeSalesCustomersNameVo;
import com.dzl.fee.service.WelfareFeeOrderService;
import com.dzl.integral.pojo.WelfareIntegralGrantDetail;
import com.dzl.integral.service.WelfareIntegralGrantDetailService;
import com.dzl.manager.ManagerService;
import com.dzl.moive.dao.WelfareMovieOrderMapper;
import com.dzl.moive.pojo.WelfareMovieCinema;
import com.dzl.moive.pojo.WelfareMovieOrder;
import com.dzl.moive.pojo.WelfareMovieOrderDetail;
import com.dzl.moive.pojo.dto.WelfareMovieOrderPayDto;
import com.dzl.moive.pojo.dto.WelfareMovieOrderRefundDto;
import com.dzl.moive.pojo.dto.WelfareMovieOrderSaveDto;
import com.dzl.moive.pojo.query.WelfareMovieOrderListQuery;
import com.dzl.moive.pojo.query.WelfareMovieOrderQuery;
import com.dzl.moive.pojo.vo.*;
import com.dzl.moive.service.WelfareMovieCinemaService;
import com.dzl.moive.service.WelfareMovieInfoService;
import com.dzl.moive.service.WelfareMovieOrderDetailService;
import com.dzl.moive.service.WelfareMovieOrderService;
import com.dzl.moive.utils.MovieConstant;
import com.dzl.moive.utils.MovieUtils;
import com.dzl.operation.service.OperationLogService;
import com.dzl.order.pojo.vo.WelfareOrderGoodsCardVo;
import com.dzl.userwx.pojo.WelfareUserWx;
import com.dzl.userwx.service.WelfareUserWxService;
import com.dzl.util.*;
import com.dzl.util.wx.WxConfig;
import com.dzl.util.wx.wxpay.WXPayConstants;
import com.dzl.util.wx.wxpay.WXPayUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.redisson.api.RLock;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 电影订单(welfare_movie_order)表服务实现类
 * @author liuguanjun
 * @since 2021-11-02 11:15:42
 */
@Slf4j
@Service("welfareMovieOrderService")
public class WelfareMovieOrderServiceImpl extends BaseServiceImpl<WelfareMovieOrder> implements WelfareMovieOrderService {

    @Autowired
    private WelfareMovieOrderMapper mapper;
    @Autowired
    private WelfareMovieOrderDetailService welfareMovieOrderDetailService;
    @Autowired
    private WelfareCardSecretService welfareCardSecretService;
    @Autowired
    private OperationLogService operationLogService;
    @Autowired
    private WelfareMovieCinemaService welfareMovieCinemaService;
    @Autowired
    private WelfareMovieInfoService welfareMovieInfoService;
    @Autowired
    private WelfareUserWxService welfareUserWxService;
    @Autowired
    private WelfareIntegralGrantDetailService welfareIntegralGrantDetailService;
    @Autowired
    private ManagerService managerService;
    @Autowired
    private WelfareEnterpriseService welfareEnterpriseService;
    @Autowired
    private WelfareFeeOrderService welfareFeeOrderService;

    @Override
    public Integer createMovieOrder(WelfareMovieOrderSaveDto welfareOrderSaveDto)throws UnsupportedEncodingException {
        Integer result = 0;
        String seatnames_ = welfareOrderSaveDto.getSeatnames();
        welfareOrderSaveDto.setSeatnames(URLEncoder.encode(seatnames_,"UTF-8"));
        String res = MovieUtils.createMovieOrder(welfareOrderSaveDto);
        JSONObject jsonObject = JSONObject.parseObject(res);
        if(jsonObject.getBoolean("success")){
            String data =  jsonObject.getString("data");
            JSONObject dataJsonObject = JSONObject.parseObject(data);
            String tradeno = dataJsonObject.getString("tradeno");
            WelfareMovieOrder welfareMovieOrder = MovieUtils.getMovieOrderDetail(tradeno);
            if(EmptyUtils.isNotEmpty(welfareMovieOrder)){
                welfareMovieOrder.setEnterpriseId(welfareOrderSaveDto.getEnterpriseId());
                welfareMovieOrder.setUserId(welfareOrderSaveDto.getUserId());
                welfareMovieOrder.setPlaytime(welfareOrderSaveDto.getPlaytime().split(" ")[1]+" "+welfareOrderSaveDto.getPlaytime().split(" ")[2]);
                welfareMovieOrder.setPlatformStatus(MovieConstant.MOVIE_ORDER_PLATFORM_STATUS.TO_BE_PAID);
                welfareMovieOrder.setOpiid(welfareOrderSaveDto.getOpiid());
                WelfareMovieOpiDetailVo opiDetailVo = MovieUtils.getOpiDetail(welfareOrderSaveDto.getOpiid());
                if(EmptyUtils.isNotEmpty(opiDetailVo)){
                    welfareMovieOrder.setClosetime(opiDetailVo.getClosetime());
                    welfareMovieOrder.setMovieid(Integer.valueOf(opiDetailVo.getMovieid()));
                    welfareMovieOrder.setCinemaid(Integer.valueOf(opiDetailVo.getCinemaid()));
                    WelfareMovieCinema welfareMovieCinema = welfareMovieCinemaService.getMovieCinemaInfo(Integer.valueOf(opiDetailVo.getCinemaid()));
                    if(EmptyUtils.isNotEmpty(welfareMovieCinema)){
                        welfareMovieOrder.setCinemaaddress(welfareMovieCinema.getAddress());
                    }
                }
                welfareMovieOrder.setCreateTime(new Date());
                welfareMovieOrder.setUpdateTime(new Date());
                String[] seatnames = seatnames_.split("\\|");
                welfareMovieOrder.setTotalAmount(new BigDecimal(welfareOrderSaveDto.getSalePrice()).multiply(new BigDecimal(seatnames.length)));
                welfareMovieOrder.setCreditsAmount(BigDecimal.ZERO);
                welfareMovieOrder.setPaymentAmount(BigDecimal.ZERO);
                welfareMovieOrder.setCreaterName(welfareOrderSaveDto.getUserName());
                mapper.insertSelective(welfareMovieOrder);
                List<WelfareMovieOrderDetail> orderDetails = new ArrayList<>();
                String[] seatids = welfareOrderSaveDto.getSeatids().split("\\|");
                String[] areas = welfareOrderSaveDto.getAreas().split("\\|");
                String[] flags = welfareOrderSaveDto.getFlags().split("\\|");
                for (int i=0;i<seatnames.length;i++) {
                    WelfareMovieOrderDetail welfareMovieOrderDetail = new WelfareMovieOrderDetail();
                    welfareMovieOrderDetail.setOrderId(welfareMovieOrder.getId());
                    welfareMovieOrderDetail.setArea(areas[i]);
                    welfareMovieOrderDetail.setCostPrice(BigDecimal.ONE);
                    welfareMovieOrderDetail.setSalePrice(BigDecimal.ONE);
                    welfareMovieOrderDetail.setSeatid(seatids[i]);
                    welfareMovieOrderDetail.setSeatname(seatnames[i]);
                    welfareMovieOrderDetail.setFlag(flags[i]);
                    welfareMovieOrderDetail.setCostPrice(new BigDecimal(welfareOrderSaveDto.getCostPrice()));
                    welfareMovieOrderDetail.setSalePrice(new BigDecimal(welfareOrderSaveDto.getSalePrice()));
                    welfareMovieOrderDetail.setCreateTime(new Date());
                    welfareMovieOrderDetail.setUpdateTime(new Date());
                    orderDetails.add(welfareMovieOrderDetail);
                }
                welfareMovieOrderDetailService.insertList(orderDetails);
                return welfareMovieOrder.getId();
            }
        }else{
            String data =  jsonObject.getString("error");
            JSONObject dataJsonObject = JSONObject.parseObject(data);
            throw new CommonException(dataJsonObject.getString("desp"));
        }
        return result;
    }

    @Override
    public PageInfo<WelfareMovieOrderVo> getWelfareMovieOrderVoListPage(WelfareMovieOrderQuery query) {
        PageHelper.startPage(query);
        List<WelfareMovieOrderVo> list = mapper.selectMovieOrderVoList(query.getUserId());
        if(EmptyUtils.isNotEmpty(list)){
            for (WelfareMovieOrderVo order:list) {
                if(order.getPlatformStatus().equals(MovieConstant.MOVIE_ORDER_PLATFORM_STATUS.PAID)){
                    long date =  DateUtil.getIntervalMillis(order.getClosetime(),DateUtil.getNow());
                    if(date>0){
                        order.setPlatformStatusName("");
                    }
                }
            }
        }
        PageInfo<WelfareMovieOrderVo> page = new PageInfo<WelfareMovieOrderVo>(list);
        return page;
    }

    @Override
    public WelfareMovieOrderVo getMovieOrderDetail(Integer orderId) {
        WelfareMovieOrderVo welfareMovieOrderVo = new WelfareMovieOrderVo();
        WelfareMovieOrder welfareMovieOrder = mapper.selectByPrimaryKey(orderId);
        BeanUtils.copyProperties(welfareMovieOrder,welfareMovieOrderVo);
        if(EmptyUtils.isNotEmpty(welfareMovieOrder.getCardSecretId())){
            WelfareUserCardSecretVo welfareUserCardSecretVo = welfareCardSecretService.getUserCardBindInfo(welfareMovieOrder.getCardSecretId());
            if(EmptyUtils.isNotEmpty(welfareUserCardSecretVo)){
                welfareMovieOrderVo.setCardPayInfo("尾号"+welfareUserCardSecretVo.getNumber().substring(3,welfareUserCardSecretVo.getNumber().length())+"福力卡");
            }else{
                welfareMovieOrderVo.setCardPayInfo("");
            }
        }else{
            welfareMovieOrderVo.setCardPayInfo("");
        }
        if(EmptyUtils.isEmpty(welfareMovieOrderVo.getOtherTradeNo())){
            welfareMovieOrderVo.setOtherTradeNo("");
        }
        //welfareMovieOrderVo.setTotalAmount(welfareMovieOrder.getCreditsAmount().add(welfareMovieOrder.getPaymentAmount()));
        if(welfareMovieOrder.getPlatformStatus() == MovieConstant.MOVIE_ORDER_PLATFORM_STATUS.CANCEL){
            welfareMovieOrderVo.setPlatformStatusName("已取消");
        }else if(welfareMovieOrder.getPlatformStatus() == MovieConstant.MOVIE_ORDER_PLATFORM_STATUS.TO_BE_PAID){
            welfareMovieOrderVo.setPlatformStatusName("待支付");
        }else if(welfareMovieOrder.getPlatformStatus() == MovieConstant.MOVIE_ORDER_PLATFORM_STATUS.PAID){
            welfareMovieOrderVo.setPlatformStatusName("已放映");
            long date =  DateUtil.getIntervalMillis(welfareMovieOrder.getClosetime(),DateUtil.getNow());
            if(date>0){
                welfareMovieOrderVo.setPlatformStatusName("已付款未放映");
                welfareMovieOrderVo.setPlatformStatus(3);
            }
        }else if(welfareMovieOrder.getPlatformStatus() == MovieConstant.MOVIE_ORDER_PLATFORM_STATUS.REFUNDED){
            welfareMovieOrderVo.setPlatformStatusName("已退款");
        }
        if(EmptyUtils.isNotEmpty(welfareMovieOrderVo.getTicketcode()) && welfareMovieOrderVo.getTicketcode().contains("取票码") && EmptyUtils.isEmpty(welfareMovieOrder.getQrcode()) && welfareMovieOrder.getPlatformStatus().equals(MovieConstant.MOVIE_ORDER_PLATFORM_STATUS.PAID)){
            String ticketcode = "";
            JSONArray jsonArray = JSONObject.parseArray(welfareMovieOrderVo.getTicketcode());
            for (Object obj:jsonArray){
                JSONArray jsonArray2 = (JSONArray) obj;
                for(Object obj2:jsonArray2){
                    JSONObject jsonObject = (JSONObject) obj2;
                    //WelfareMovieOrderTicketcodeList welfareMovieOrderTicketcodeList = JSONObject.parseObject(jsonObject.toJSONString(), WelfareMovieOrderTicketcodeList.class);
                    if(EmptyUtils.isNotEmpty(jsonObject)){
                        ticketcode = ticketcode+jsonObject.getString("value")+"|";
                    }
                }
            }
            if(EmptyUtils.isNotEmpty(ticketcode)){
                String qrcode = QRCode.getMovieOrderTicketQrCode(ticketcode.substring(0,ticketcode.length()-1));
                if(EmptyUtils.isNotEmpty(qrcode)){
                    welfareMovieOrderVo.setQrcode(qrcode);
                    welfareMovieOrder.setQrcode(qrcode);
                    mapper.updateByPrimaryKeySelective(welfareMovieOrder);
                }else{
                    welfareMovieOrderVo.setQrcode("");
                }
            }
        }
        if(EmptyUtils.isEmpty(welfareMovieOrderVo.getQrcode())){
            welfareMovieOrderVo.setQrcode("");
        }
        if(EmptyUtils.isEmpty(welfareMovieOrderVo.getTicketcode())){
            welfareMovieOrderVo.setTicketcode("");
        }
        WelfareMovieCinema welfareMovieCinema = welfareMovieCinemaService.getMovieCinemaInfo(welfareMovieOrder.getCinemaid());
        if(EmptyUtils.isNotEmpty(welfareMovieCinema)){
            welfareMovieOrderVo.setLat(welfareMovieCinema.getLat());
            welfareMovieOrderVo.setLon(welfareMovieCinema.getLon());
        }
        return welfareMovieOrderVo;
    }


    @Override
    public Boolean cancelMovieOrder(String tradeno, String cancelRemark) {
        String result = MovieUtils.cancelMovieOrder(tradeno);
        JSONObject jsonObject = JSONObject.parseObject(result);
        Boolean b = jsonObject.getBoolean("success");
        if(b){
            //修改订单状态为已取消
            Example example_ = new Example(WelfareMovieOrder.class);
            example_.createCriteria().andEqualTo("tradeno", tradeno);
            WelfareMovieOrder updateWelfareMovieOrderParam = new WelfareMovieOrder();
            updateWelfareMovieOrderParam.setUpdateTime(new Date());
            updateWelfareMovieOrderParam.setCancelTime(new Date());
            updateWelfareMovieOrderParam.setRemark(cancelRemark);
            updateWelfareMovieOrderParam.setPlatformStatus(MovieConstant.MOVIE_ORDER_PLATFORM_STATUS.CANCEL);
            mapper.updateByExampleSelective(updateWelfareMovieOrderParam,example_);
        }else{
            WelfareMovieOrder query = new WelfareMovieOrder();
            query.setTradeno(tradeno);
            WelfareMovieOrder order = mapper.selectOne(query);
            if(EmptyUtils.isNotEmpty(order)){
                String tradeno_ = MovieUtils.getUnpaidMovieOrder(order.getMobile());
                if(EmptyUtils.isEmpty(tradeno_)){
                    //修改订单状态为已取消
                    order.setPlatformStatus(MovieConstant.MOVIE_ORDER_PLATFORM_STATUS.CANCEL);
                    order.setUpdateTime(new Date());
                    order.setCancelTime(new Date());
                    order.setRemark(cancelRemark);
                    mapper.updateByPrimaryKeySelective(order);
                    return true;
                }
            }
        }
        return b;
    }

    @Override
    public List<WelfareMovieOrder> selectUnpaidMovieOrder() {
        return mapper.selectUnpaidMovieOrder();
    }

    @Override
    public String getUnpaidMovieOrder(String mobile) {
        return MovieUtils.getUnpaidMovieOrder(mobile);
    }



    @Override
    public WelfareMovieOrderPayVo getPayMatchCardsByOrderId(Integer userId, Integer orderId, Integer cardSecretId) {
        WelfareMovieOrderPayVo welfareMovieOrderVo = new WelfareMovieOrderPayVo();
        welfareMovieOrderVo.setPayMethod(MovieConstant.MOVIE_ORDER_PAY_METHOD.CARD);
        // 获取用户可用卡列表
        List<WelfareUserCardSecretVo> welfareCardSecretList = welfareCardSecretService.getUserCardBindListForOrderPay(userId);
        // 以卡密id为key，将匹配到的商品放到放到商品列表的HashMap中
        Map<Integer, List<WelfareOrderGoodsCardVo>> map = new HashMap<>();
        //当前选中卡
        Integer checkCardSecretId = 0 ;
        BigDecimal checkCardAmount = BigDecimal.ZERO;
        // 电影卡列表
        List<WelfareUserCardSecretVo> welfareCardSecretMovieList = welfareCardSecretList.stream().filter(s -> s.getCardPartitionIds().contains(1)).collect(Collectors.toList());
        // 通兑卡列表
        List<WelfareUserCardSecretVo> welfareCardSecretCommonList = welfareCardSecretList.stream().filter(s -> s.getCardPartitionIds().contains(0)).collect(Collectors.toList());
        //将电影卡和通兑卡筛选出来
        welfareCardSecretList = new ArrayList<>();
        if(EmptyUtils.isNotEmpty(welfareCardSecretMovieList)){
            if(cardSecretId!=null){
                for (WelfareUserCardSecretVo cardSecret:welfareCardSecretMovieList) {
                    if(cardSecret.getId().equals(cardSecretId)){
                        checkCardSecretId = cardSecret.getId();
                        checkCardAmount = cardSecret.getRemainAmount();
                    }
                }
            }else{
                checkCardSecretId = welfareCardSecretMovieList.get(0).getId();
                checkCardAmount = welfareCardSecretMovieList.get(0).getRemainAmount();
            }
            welfareCardSecretList.addAll(welfareCardSecretMovieList);
        }
        if(EmptyUtils.isNotEmpty(welfareCardSecretCommonList)){
            if(cardSecretId!=null){
                for (WelfareUserCardSecretVo cardSecret:welfareCardSecretCommonList) {
                    if(cardSecret.getId().equals(cardSecretId)){
                        checkCardSecretId = cardSecret.getId();
                        checkCardAmount = cardSecret.getRemainAmount();
                    }
                }
            }else{
                if(checkCardSecretId==0){
                    checkCardSecretId = welfareCardSecretCommonList.get(0).getId();
                    checkCardAmount = welfareCardSecretCommonList.get(0).getRemainAmount();
                }
            }
            welfareCardSecretList.addAll(welfareCardSecretCommonList);
        }
        // 按照剩余额额度排序
        if(EmptyUtils.isNotEmpty(welfareCardSecretList)){
            welfareCardSecretList = welfareCardSecretList.stream().sorted(Comparator.comparing(WelfareUserCardSecretVo::getRemainAmount).reversed()).collect(Collectors.toList());
        }
        //查询电影信息
        WelfareMovieOrder movieOrder = mapper.selectByPrimaryKey(orderId);
        BeanUtils.copyProperties(movieOrder,welfareMovieOrderVo);
        //welfareMovieOrderVo.setTotalAmount(movieOrder.getCreditsAmount().add(movieOrder.getPaymentAmount()));
        BigDecimal paymentAmount = BigDecimal.ZERO;
        if(checkCardAmount.compareTo(welfareMovieOrderVo.getTotalAmount())==-1){
            paymentAmount = welfareMovieOrderVo.getTotalAmount().subtract(checkCardAmount);
        }
        welfareMovieOrderVo.setPaymentAmount(paymentAmount);
        welfareMovieOrderVo.setCardPayedAmount(welfareMovieOrderVo.getTotalAmount().subtract(paymentAmount));
        welfareMovieOrderVo.setOrderId(movieOrder.getId());
        welfareMovieOrderVo.setCheckCardSecretId(checkCardSecretId);
        welfareMovieOrderVo.setCardSecretList(welfareCardSecretList);
        if(welfareMovieOrderVo.getPaymentAmount().compareTo(BigDecimal.ZERO)==1 && checkCardSecretId==0){//如果现金支付大于0且未选择卡，则微信支付
            welfareMovieOrderVo.setPayMethod(MovieConstant.MOVIE_ORDER_PAY_METHOD.WEIXIN);
        }else if(welfareMovieOrderVo.getPaymentAmount().compareTo(BigDecimal.ZERO)==1 && checkCardSecretId!=0){//如果现金支付大于0且选择卡，则微信支付+卡支付
            welfareMovieOrderVo.setPayMethod(MovieConstant.MOVIE_ORDER_PAY_METHOD.CARD_AND_WEIXIN);
        }
        return welfareMovieOrderVo;
    }

    @Override
    public WelfareMovieOrderPayVo getPayInfoByOrderId(Integer userId, Integer orderId) {
        WelfareMovieOrderPayVo welfareMovieOrderVo = new WelfareMovieOrderPayVo();
        welfareMovieOrderVo.setPayMethod(MovieConstant.MOVIE_ORDER_PAY_METHOD.CARD);
        //查询用户信息
        WelfareUserWx userWx = welfareUserWxService.selectByPrimaryKey(userId);
        //查询电影信息
        WelfareMovieOrder movieOrder = mapper.selectByPrimaryKey(orderId);
        BeanUtils.copyProperties(movieOrder,welfareMovieOrderVo);
        welfareMovieOrderVo.setCurrentBalanceIntegral(userWx.getBalanceIntegral());
        //welfareMovieOrderVo.setTotalAmount(movieOrder.getCreditsAmount().add(movieOrder.getPaymentAmount()));
        BigDecimal paymentAmount = BigDecimal.ZERO;
        if(userWx.getBalanceIntegral().compareTo(BigDecimal.ZERO)!=1){//若用户可用积分<=0，则微信支付
            paymentAmount = welfareMovieOrderVo.getTotalAmount();
            welfareMovieOrderVo.setPayMethod(MovieConstant.MOVIE_ORDER_PAY_METHOD.WEIXIN);
        }else if(userWx.getBalanceIntegral().compareTo(welfareMovieOrderVo.getTotalAmount())==-1){//若用户可用积分<订单金额，则微信支付+卡支付
            paymentAmount = welfareMovieOrderVo.getTotalAmount().subtract(userWx.getBalanceIntegral());
            welfareMovieOrderVo.setPayMethod(MovieConstant.MOVIE_ORDER_PAY_METHOD.CARD_AND_WEIXIN);
        }else if(userWx.getBalanceIntegral().compareTo(welfareMovieOrderVo.getTotalAmount())!=-1){//若可用积分>=订单金额,则卡支付
            welfareMovieOrderVo.setPayMethod(MovieConstant.MOVIE_ORDER_PAY_METHOD.CARD);
        }
        welfareMovieOrderVo.setPaymentAmount(paymentAmount);
        welfareMovieOrderVo.setCardPayedAmount(welfareMovieOrderVo.getTotalAmount().subtract(paymentAmount));
        welfareMovieOrderVo.setOrderId(movieOrder.getId());
        welfareMovieOrderVo.setCheckCardSecretId(0);
        return welfareMovieOrderVo;
    }

    @Override
    public Map saveMovieOrderToPay(WelfareUserWx user, WelfareMovieOrderPayDto wlfareMovieOrderPayDto) {
        Map<String, Object> map = new HashMap<>();
        map.put("code", 1000);
        map.put("msg", "现金支付异常");
        //查询电影信息
        WelfareMovieOrder movieOrder = mapper.selectByPrimaryKey(wlfareMovieOrderPayDto.getOrderId());
        if(EmptyUtils.isNotEmpty(movieOrder) ){
            if(movieOrder.getPlatformStatus()==MovieConstant.MOVIE_ORDER_PLATFORM_STATUS.CANCEL){
                map.put("msg", "该订单超时已取消,请重新下单");
                return map;
            }else if(movieOrder.getPlatformStatus() > 0){
                map.put("msg", "该订单已支付过");
                return map;
            }
        }else{
            map.put("msg", "该订单不存在");
            return map;
        }
        //修改订单卡支付金额和现金支付金额
        movieOrder.setCardSecretId(EmptyUtils.isNotEmpty(wlfareMovieOrderPayDto.getCardSecretId())&&wlfareMovieOrderPayDto.getCardSecretId()>0?wlfareMovieOrderPayDto.getCardSecretId():null);
        movieOrder.setOutTradeNo(StringUtil.getBillNumber());
        movieOrder.setCreditsAmount(movieOrder.getTotalAmount().subtract(wlfareMovieOrderPayDto.getPaymentAmount()));
        movieOrder.setPaymentAmount(wlfareMovieOrderPayDto.getPaymentAmount());
        mapper.updateByPrimaryKeySelective(movieOrder);
        if(movieOrder.getEnterpriseId() .equals(0)){//福力兔，卡支付
            //如果仅用卡支付，则扣除卡积分
            if(EmptyUtils.isNotEmpty(wlfareMovieOrderPayDto.getCardSecretId()) && wlfareMovieOrderPayDto.getPaymentAmount().compareTo(BigDecimal.ZERO)==0){
                //通知嘟嘟电影api修改订单支付状态
                boolean b = MovieUtils.updateMovieOrderPayNotify(movieOrder.getTradeno(),movieOrder.getOutTradeNo());
                if(b){
                    //查询卡密信息，并修改卡可用积分和已用积分
                    WelfareCardSecret welfareCardSecret = welfareCardSecretService.selectByPrimaryKey(wlfareMovieOrderPayDto.getCardSecretId());
                    welfareCardSecret.setUsedAmount(welfareCardSecret.getUsedAmount().add(movieOrder.getCreditsAmount()));
                    welfareCardSecret.setRemainAmount(welfareCardSecret.getRemainAmount().subtract(movieOrder.getCreditsAmount()));
                    welfareCardSecret.setUpdateTime(new Date());
                    welfareCardSecretService.updateByPrimaryKeySelective(welfareCardSecret);
                    //修改订单状态为已支付并修改支付日期
                    //movieOrder.setOtherTradeNo(transactionId);
                    movieOrder.setPlatformStatus(MovieConstant.MOVIE_ORDER_PLATFORM_STATUS.PAID);
                    movieOrder.setPayTime(new Date());
                    movieOrder.setUpdateTime(new Date());
                    movieOrder.setPaymentAmount(BigDecimal.ZERO);
                    mapper.updateByPrimaryKeySelective(movieOrder);
                    //修改电影票销售数量
                    welfareMovieInfoService.updateMovieSaleCount(movieOrder.getMovieid(), Integer.valueOf(movieOrder.getQuantity()));
                    //修改订单支付状态
                    WelfareMovieOrder welfareMovieOrder = MovieUtils.getMovieOrderDetail(movieOrder.getTradeno());
                    if(EmptyUtils.isNotEmpty(welfareMovieOrder) && !welfareMovieOrder.getOrderstatus().equals(movieOrder.getOrderstatus())){
                        movieOrder.setOrderstatus(welfareMovieOrder.getOrderstatus());
                        movieOrder.setRefundReason(welfareMovieOrder.getRefundReason());
                        movieOrder.setSmscontent(welfareMovieOrder.getSmscontent());
                        movieOrder.setUpdateTime(new Date());
                        movieOrder.setTicketcode(welfareMovieOrder.getTicketcode());
                        mapper.updateByPrimaryKeySelective(movieOrder);
                    }
                    map.put("orderId", movieOrder.getId());
                    map.put("code", 200);
                    map.put("msg", "success");
                    return map;
                }
                map.put("code", 1001);
                map.put("msg", "第三方api支付回调失败");
                return map;
            }else{
                map.put("orderId", movieOrder.getId());
                map.put("code", 200);
                map.put("msg", "success");
                return map;
            }
        }else{//兔福宝，积分支付
            WelfareUserWx user_ = welfareUserWxService.selectByPrimaryKey(user.getId());
            //纯积分支付
            if(user_.getBalanceIntegral().compareTo(movieOrder.getTotalAmount())!=-1){
                //通知嘟嘟电影api修改订单支付状态
                boolean b = MovieUtils.updateMovieOrderPayNotify(movieOrder.getTradeno(),movieOrder.getOutTradeNo());
                if(b){
                    //查询用户信息，并修改卡可用积分和已用积分
                    //WelfareUserWx user_ = welfareUserWxService.selectByPrimaryKey(user.getId());
                    user_.setBalanceIntegral(user_.getBalanceIntegral().subtract(movieOrder.getTotalAmount()));
                    user_.setConsumeIntegral(user_.getConsumeIntegral().add(movieOrder.getTotalAmount()));
                    user_.setUpdateTime(new Date());
                    welfareUserWxService.updateByPrimaryKeySelective(user_);
                    // 插入积分消费明细
                    WelfareIntegralGrantDetail WelfareIntegralGrantDetailAdd = new WelfareIntegralGrantDetail();
                    WelfareIntegralGrantDetailAdd.setCreateTime(new Date());
                    WelfareIntegralGrantDetailAdd.setType(2);
                    WelfareIntegralGrantDetailAdd.setUserId(movieOrder.getUserId());
                    WelfareIntegralGrantDetailAdd.setGrantIntegral(movieOrder.getTotalAmount());
                    welfareIntegralGrantDetailService.insert(WelfareIntegralGrantDetailAdd);
                    //修改订单状态为已支付并修改支付日期
                    movieOrder.setPlatformStatus(MovieConstant.MOVIE_ORDER_PLATFORM_STATUS.PAID);
                    movieOrder.setPayTime(new Date());
                    movieOrder.setUpdateTime(new Date());
                    movieOrder.setPaymentAmount(BigDecimal.ZERO);
                    mapper.updateByPrimaryKeySelective(movieOrder);
                    //修改电影票销售数量
                    welfareMovieInfoService.updateMovieSaleCount(movieOrder.getMovieid(), Integer.valueOf(movieOrder.getQuantity()));
                    //修改订单支付状态
                    WelfareMovieOrder welfareMovieOrder = MovieUtils.getMovieOrderDetail(movieOrder.getTradeno());
                    if(EmptyUtils.isNotEmpty(welfareMovieOrder) && !welfareMovieOrder.getOrderstatus().equals(movieOrder.getOrderstatus())){
                        movieOrder.setOrderstatus(welfareMovieOrder.getOrderstatus());
                        movieOrder.setRefundReason(welfareMovieOrder.getRefundReason());
                        movieOrder.setSmscontent(welfareMovieOrder.getSmscontent());
                        movieOrder.setUpdateTime(new Date());
                        movieOrder.setTicketcode(welfareMovieOrder.getTicketcode());
                        mapper.updateByPrimaryKeySelective(movieOrder);
                    }
                    map.put("orderId", movieOrder.getId());
                    map.put("code", 200);
                    map.put("msg", "success");
                    return map;
                }
                map.put("code", 1001);
                map.put("msg", "第三方api支付回调失败");
                return map;
            }else{
                if(user_.getBalanceIntegral().add(wlfareMovieOrderPayDto.getPaymentAmount()).compareTo(movieOrder.getTotalAmount())!=0){
                    map.put("msg", "支付金额与实付金额不一致");
                    return map;
                }else{
                    map.put("orderId", movieOrder.getId());
                    map.put("code", 200);
                    map.put("msg", "success");
                    return map;
                }
            }
        }
    }

    /**
     * 微信支付
     * @param orderId 订单ID
     * @param openId       微信openId
     * @return java.util.Map
     * @author ChenLong
     * @date 2021-06-06 12:42:04
     **/
    @Override
    public Map weChatPayForApplet(Integer orderId , String openId) throws Exception {
        WelfareMovieOrder welfareOrder = mapper.selectByPrimaryKey(orderId);
        log.info("weChatPayForApplet in: " + welfareOrder.toString());
        Map<String, Object> map = new HashMap<>();
        // 微信支付
        if (EmptyUtils.isEmpty(welfareOrder.getPaymentAmount())) {
            map.put("code", 1002);
            map.put("msg", "现金支付异常");
            return map;
        }
        WelfareEnterprise welfareEnterprise = welfareEnterpriseService.selectByPrimaryKey(welfareOrder.getEnterpriseId());
        if(EmptyUtils.isEmpty(welfareEnterprise) || EmptyUtils.isEmpty(welfareEnterprise.getAppid()) || EmptyUtils.isEmpty(welfareEnterprise.getAppsecret())
                || EmptyUtils.isEmpty(welfareEnterprise.getMchId()) || EmptyUtils.isEmpty(welfareEnterprise.getMchKey())){
            map.put("code", 1002);
            map.put("msg", "现金支付异常:缺少小程序独立部署配置参数");
            return map;
        }
        // 微信支付日志JSONObject
        JSONObject logJsonObj = new JSONObject();
        BigDecimal totalFee = WXPayUtil.calcWxPayPrice(welfareOrder.getPaymentAmount());
        log.info("weChatPayForApplet totalFee: " + totalFee);
        String body = "福力兔产品购买";
        String notifyUrl = WxConfig.PAY_NOTIFY_MOVIE_ORDER_APPLET_URL;
        String appId = welfareEnterprise.getAppid(); //WxConfig.WX_XCX_APPID;
        String mchId = welfareEnterprise.getMchId(); //WxConfig.WX_PARTNER;
        String key = welfareEnterprise.getMchKey(); // WxConfig.WX_PARTNER_KEY;
        if(!welfareOrder.getEnterpriseId().equals(0)){
            body = "兔福宝产品购买";
            //notifyUrl = WxConfig.PAY_NOTIFY_MOVIE_ORDER_SAASAPPLET_URL;
            appId = WxConfig.WX_XCX_SASS_APPID;
            mchId = WxConfig.WX_PARTNER;
            key = WxConfig.WX_PARTNER_KEY;
        }
        String xml = WXPayUtil.generateSignature(appId, mchId, key,
                notifyUrl, totalFee, welfareOrder.getOutTradeNo(), openId, body);
        Object result = HttpRequest.post(WxConfig.PAY_UNIFIEDORDER_URL, xml, 0);
        log.info("weChatPayForApplet result: " + result);
        if (EmptyUtils.isEmpty(result)) {
            logJsonObj.put("code", 1003);
            logJsonObj.put("params", xml);
            logJsonObj.put("outTradeNo", welfareOrder.getOutTradeNo());
            operationLogService.saveOperationLog(welfareOrder.getId(), "weChatPayForApplet pay failed: " + logJsonObj.toString(), OperationConstant.TypeEnum.MOVIE_ORDER_WEIXIN_PAY_FAIL.getType(),-1,null);
            map.put("code", 1003);
            map.put("msg", "微信支付失败");
            return map;
        }
        Map<String, String> resultMap = WXPayUtil.readStringXmlOut(result.toString());
        if ((WXPayConstants.SUCCESS).equals(MapUtils.getString(resultMap, "result_code"))) {
            String prepayId = resultMap.get("prepay_id");
            Map mapRes = WXPayUtil.signMapById(appId, prepayId, WxConfig.WX_PARTNER_KEY);
            // 微信支付日志JSONObject
            logJsonObj.put("code", 200);
            logJsonObj.put("params", xml);
            logJsonObj.put("result", result);
            logJsonObj.put("outTradeNo", welfareOrder.getOutTradeNo());
            operationLogService.saveOperationLog(welfareOrder.getId(), "weChatPayForApplet pay success: " + logJsonObj.toString(), OperationConstant.TypeEnum.MOVIE_ORDER_WEIXIN_PAY_SUCCESS.getType(),null,null);
            mapRes.put("orderId", welfareOrder.getId());
            mapRes.put("code", 200);
            mapRes.put("msg", "success");
            return mapRes;
        } else {
            // 微信支付日志JSONObject
            logJsonObj.put("code", 1004);
            logJsonObj.put("params", xml);
            logJsonObj.put("result", result);
            logJsonObj.put("outTradeNo", welfareOrder.getOutTradeNo());
            operationLogService.saveOperationLog(welfareOrder.getId(), "weChatPayForApplet pay failed: " + logJsonObj.toString(), OperationConstant.TypeEnum.MOVIE_ORDER_WEIXIN_PAY_FAIL.getType(),null,null);
            map.put("code", 1004);
            map.put("msg", "微信支付失败");
            return map;
        }
    }

    /**
     * 微信支付回调接口
     * @param request 回调request对象
     * @return java.lang.String
     * @author ChenLong
     * @date 2021-05-26 12:25:14
     **/
    @Override
    public String updateSettlementNotify(HttpServletRequest request) throws Exception {
        log.info("updateSettlementNotify in");
        request.setCharacterEncoding("utf-8");
        BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
        String line;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        log.info("updateSettlementNotify xml: " + sb.toString());
        Map<String, String> map = WXPayUtil.readStringXmlOut(sb.toString());
        String outTradeNo = map.get("out_trade_no");
        String transactionId = map.get("transaction_id");
        String totalFee = map.get("total_fee");
        // 微信支付日志JSONObject
        JSONObject logJsonObj = new JSONObject();
        if (StringUtils.isBlank(outTradeNo) || StringUtils.isBlank(transactionId)) {
            logJsonObj.put("msg", "call back for outTradeNo or transactionId blank");
            logJsonObj.put("result", map);
            operationLogService.saveOperationLog(0, "WeChat callback failed: " + logJsonObj.toString(), OperationConstant.TypeEnum.MOVIE_ORDER_WEIXIN_PAY_NOTIFY_FAIL.getType(),null,null);
            log.info("updateSettlementNotify params error outTradeNo :{}, transactionId :{}", outTradeNo, transactionId);
            return WXPayConstants.FAIL;
        }
        // 校验参数
        Map<String, String> validateMap = WXPayUtil.xmlToMap(sb.toString());
        if (!WXPayUtil.isSignatureValid(validateMap, WxConfig.WX_PARTNER_KEY)) {
            logJsonObj.put("msg", "call back for isSignatureValid fail");
            logJsonObj.put("result", map);
            operationLogService.saveOperationLog(0, "WeChat callback failed: " + logJsonObj.toString(), OperationConstant.TypeEnum.MOVIE_ORDER_WEIXIN_PAY_NOTIFY_FAIL.getType(),null,null);
            log.info("updateSettlementNotify isSignatureValid fail");
            return WXPayConstants.FAIL;
        }
        // 校验订单支付状态
        WelfareMovieOrder query = new WelfareMovieOrder();
        query.setOutTradeNo(outTradeNo);
        WelfareMovieOrder movieOrder = mapper.selectOne(query);
        // 订单状态发生了变化
        if (null == movieOrder || !movieOrder.getPlatformStatus().equals(MovieConstant.MOVIE_ORDER_PLATFORM_STATUS.TO_BE_PAID)) {
            logJsonObj.put("msg", "call back for welfareOrder is null or error status");
            logJsonObj.put("result", map);
            Integer orderId = 0;
            if (EmptyUtils.isNotEmpty(movieOrder) && EmptyUtils.isNotEmpty(movieOrder.getId())) {
                orderId = movieOrder.getId();
            }
            operationLogService.saveOperationLog(orderId, "WeChat callback message: " + logJsonObj.toString(), OperationConstant.TypeEnum.MOVIE_ORDER_WEIXIN_PAY_NOTIFY_FAIL.getType(),null,null);
            log.info("updateSettlementNotify welfareOrder is null or error status");
            return WXPayConstants.FAIL;
        }
        // 正式服校验支付金额
        if (!"0".equals(ApplicationConfiguration.getInstance().getIsProduct()) && (null == totalFee || !WXPayUtil.calcWxPayPrice(movieOrder.getPaymentAmount()).toString().equals(totalFee))) {
            logJsonObj.put("msg", "call back for getInstance null");
            logJsonObj.put("result", map);
            operationLogService.saveOperationLog(movieOrder.getId(), "WeChat callback failed: " + logJsonObj.toString(), OperationConstant.TypeEnum.MOVIE_ORDER_WEIXIN_PAY_NOTIFY_FAIL.getType(),null,null);
            log.info("updateSettlementNotify getInstance null");
            return WXPayConstants.FAIL;
        }
        try {
            //通知嘟嘟电影api修改订单支付状态
            boolean b = MovieUtils.updateMovieOrderPayNotify(movieOrder.getTradeno(),movieOrder.getOutTradeNo());
            if(b){
                //修改订单状态为已支付并修改支付日期
                movieOrder.setOtherTradeNo(transactionId);
                movieOrder.setPlatformStatus(MovieConstant.MOVIE_ORDER_PLATFORM_STATUS.PAID);
                movieOrder.setPayTime(new Date());
                movieOrder.setUpdateTime(new Date());
                //welfareOrder.setPaymentAmount(new BigDecimal(totalFee).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN));
                mapper.updateByPrimaryKeySelective(movieOrder);
                //修改电影票销售数量
                welfareMovieInfoService.updateMovieSaleCount(movieOrder.getMovieid(), Integer.valueOf(movieOrder.getQuantity()));
                //福力兔，卡支付
                if(movieOrder.getEnterpriseId().equals(0)){
                    //如果使用卡支付的，则修改卡可用积分和已用积分
                    if(EmptyUtils.isNotEmpty(movieOrder.getCardSecretId())){
                        //查询卡密信息
                        WelfareCardSecret welfareCardSecret = welfareCardSecretService.selectByPrimaryKey(movieOrder.getCardSecretId());
                        if(EmptyUtils.isNotEmpty(welfareCardSecret)){
                            welfareCardSecret.setUsedAmount(welfareCardSecret.getUsedAmount().add(movieOrder.getCreditsAmount()));
                            welfareCardSecret.setRemainAmount(welfareCardSecret.getRemainAmount().subtract(movieOrder.getCreditsAmount()));
                            welfareCardSecret.setUpdateTime(new Date());
                            welfareCardSecretService.updateByPrimaryKeySelective(welfareCardSecret);
                        }
                    }
                }else{
                    //兔福宝，积分支付
                    //如果使用积分支付的，则修改用户可用积分和已用积分
                    if(movieOrder.getCreditsAmount().compareTo(BigDecimal.ZERO)==1){
                        WelfareUserWx user_ = welfareUserWxService.selectByPrimaryKey(movieOrder.getUserId());
                        user_.setBalanceIntegral(user_.getBalanceIntegral().subtract(movieOrder.getCreditsAmount()));
                        user_.setConsumeIntegral(user_.getConsumeIntegral().add(movieOrder.getCreditsAmount()));
                        user_.setUpdateTime(new Date());
                        welfareUserWxService.updateByPrimaryKeySelective(user_);
                        // 插入积分消费明细
                        WelfareIntegralGrantDetail WelfareIntegralGrantDetailAdd = new WelfareIntegralGrantDetail();
                        WelfareIntegralGrantDetailAdd.setCreateTime(new Date());
                        WelfareIntegralGrantDetailAdd.setType(2);
                        WelfareIntegralGrantDetailAdd.setUserId(movieOrder.getUserId());
                        WelfareIntegralGrantDetailAdd.setGrantIntegral(movieOrder.getCreditsAmount());
                        welfareIntegralGrantDetailService.insert(WelfareIntegralGrantDetailAdd);
                    }
                }
                //修改订单支付状态
                WelfareMovieOrder welfareMovieOrder = MovieUtils.getMovieOrderDetail(movieOrder.getTradeno());
                if(EmptyUtils.isNotEmpty(welfareMovieOrder) && !welfareMovieOrder.getOrderstatus().equals(movieOrder.getOrderstatus())){
                    movieOrder.setOrderstatus(welfareMovieOrder.getOrderstatus());
                    movieOrder.setRefundReason(welfareMovieOrder.getRefundReason());
                    movieOrder.setSmscontent(welfareMovieOrder.getSmscontent());
                    movieOrder.setUpdateTime(new Date());
                    movieOrder.setTicketcode(welfareMovieOrder.getTicketcode());
                    mapper.updateByPrimaryKeySelective(movieOrder);
                }
                // 发送短信（兑换虚拟订单发送兑换码）、充值类的不发验证码
                /*if (!welfareOrder.getOrderType().equals(WelfareOrderTypeEnum.ORDER_TYPE_VIRTUAL_API_RECHARGE.getCode())) {
                    welfareOrderService.sendMessageForPayByOrder(welfareOrder);
                }*/
                operationLogService.saveOperationLog(movieOrder.getId(), "WeChat callback success: " + map, OperationConstant.TypeEnum.MOVIE_ORDER_WEIXIN_PAY_NOTIFY_SUCCESS.getType(),null,null);
                log.info("updateSettlementNotify WeChat callback success: " + map);
                return WXPayConstants.SUCCESS;
            }
            return WXPayConstants.FAIL;
        } catch (Exception e) {
            operationLogService.saveOperationLog(movieOrder.getId(), "WeChat callback failed: " + map, OperationConstant.TypeEnum.MOVIE_ORDER_WEIXIN_PAY_NOTIFY_FAIL.getType(),null,null);
            log.info("updateSettlementNotifyWeChat callback failed: " + map);
            return WXPayConstants.FAIL;
        }
    }

    @Override
    public void exportOrderFlowList(WelfareMovieOrderListQuery query, Integer dataType,HttpServletResponse res, HttpServletRequest req) {
        List<List<String>> data = new ArrayList<>();
        List<WelfareMovieOrderListVo> list = getMovieOrderVoList(query);
        if(EmptyUtils.isNotEmpty(list)) {
            for(WelfareMovieOrderListVo x : list) {
                List<String> rowData = new ArrayList<>();
                rowData.add(x.getTradeno());
                rowData.add(x.getOrderTypeName());
                rowData.add(DateUtil.format2DateTime(x.getCreateTime()));
                rowData.add(x.getPlatformStatusName());
                rowData.add(x.getMoviename());
                rowData.add(x.getCinemaname());
                rowData.add(x.getRoomname());
                rowData.add(x.getPlaytime());
                rowData.add(x.getSeatNames());
                rowData.add(x.getSeatNamesSalePrice());
                if(dataType == 0){
                    rowData.add(x.getSeatNamesCostPrice());
                }
                rowData.add(x.getSeatNamesSupplyPrice());
                rowData.add(x.getOrderTotalAmount().toString());
                if(dataType == 0){
                    rowData.add(x.getCostTotalAmount().toString());
                }
                rowData.add(x.getSupplyTotalAmount().toString());
                rowData.add(x.getCreditsAmount().toString());
                rowData.add(x.getPaymentAmount().toString());
                rowData.add(x.getCardNo());
                rowData.add(x.getSupplierName());
                if (EmptyUtils.isNotEmpty(x.getPaymentAmount())) {
                    rowData.add(x.getOutTradeNo());
                } else {
                    rowData.add("-");
                }
                if (EmptyUtils.isNotEmpty(x.getRefundTime())) {
                    rowData.add(DateUtil.format2DateTime(x.getRefundTime()));
                } else {
                    rowData.add("-");
                }
                rowData.add(x.getCardCustomers());
                data.add(rowData);
            }
        }
        OutputStream os = null;
        try{

            HSSFWorkbook workbook = new HSSFWorkbook();
            String fileName = "电影订单流水" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".xls";
            res.setHeader("Content-disposition", "attachment; filename=" + fileName);
            res.setContentType("application/vnd.ms-excel;charset=utf-8");
            os = res.getOutputStream();
            if(dataType == 0){
                String[] headers = {"订单编号","订单类型","下单时间","订单状态","电影名称","影院名称","影厅名称","放映时间","座位信息",
                        "电影销售价","电影成本价","供应价","销售总计","成本总计","供应价总计","用户支付福力","用户补差","支付卡号","供应商名称","微信流水号",
                        "退款时间","客户名称"};
                ExcelUtil.exportExcel(workbook, 0, "Page1", headers, data, os);
            }else{
                String[] headers = {"订单编号","订单类型","下单时间","订单状态","电影名称","影院名称","影厅名称","放映时间","座位信息",
                        "电影销售价","供应价","销售总计","供应价总计","用户支付福力","用户补差","支付卡号","供应商名称","微信流水号",
                        "退款时间","客户名称"};
                ExcelUtil.exportExcel(workbook, 0, "Page1", headers, data, os);
            }
            workbook.write(os);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                assert os != null;
                os.flush();
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public List<Integer> getMovieOrderCount(WelfareMovieOrderListQuery query) {
        return mapper.getMovieOrderCount(query);
    }

    public List<WelfareMovieOrderListVo> getMovieOrderVoList(WelfareMovieOrderListQuery query) {
        List<WelfareMovieOrderListVo> list = mapper.getMovieOrderVoPage(query);
        if(EmptyUtils.isNotEmpty(list)) {
            for (WelfareMovieOrderListVo x : list) {
                x.setOrderTypeName("电影订单");
                x.setSupplierName("嘟电影");
                x.setPartitionName("电影专区");
                x.setOrderSourceType("小程序");
                Integer orderId = x.getId();
                Example detailExp = new Example(WelfareMovieOrderDetail.class);
                detailExp.createCriteria().andEqualTo("orderId", orderId);
                BigDecimal originalAmount = new BigDecimal(x.getOriginalamount());
                BigDecimal profitAmount = x.getOrderTotalAmount().subtract(originalAmount);
                BigDecimal profitRateBigDecimal = profitAmount.divide(originalAmount, 4, BigDecimal.ROUND_HALF_UP);
                String profitRate = profitRateBigDecimal.multiply(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_HALF_UP).toString() + "%";
                x.setProfitRate(profitRate);
                List<WelfareMovieOrderDetail> detailList =  welfareMovieOrderDetailService.selectByExample(detailExp);
                StringBuilder seatNames = new StringBuilder();
                StringBuilder seatNamesCostPrice = new StringBuilder();
                StringBuilder seatNamesSalePrice = new StringBuilder();
                StringBuilder seatNamesSupplyPrice = new StringBuilder();
                BigDecimal costTotalAmount = BigDecimal.ZERO;
                BigDecimal saleTotalAmount = BigDecimal.ZERO;
                BigDecimal supplyTotalAmount = BigDecimal.ZERO;
                for(WelfareMovieOrderDetail y : detailList) {
                    if(EmptyUtils.isEmpty(y.getSupplyPrice()) || y.getSupplyPrice().compareTo(BigDecimal.ZERO)!=1){
                        y.setSupplyPrice(y.getSalePrice());
                    }
                    seatNames.append(y.getSeatname()).append("、");
                    costTotalAmount = costTotalAmount.add(y.getCostPrice());
                    saleTotalAmount = saleTotalAmount.add(y.getSalePrice());
                    supplyTotalAmount = supplyTotalAmount.add(y.getSupplyPrice());
                    y.setSupplyPrice(y.getSalePrice());
                    seatNamesCostPrice.append(y.getSeatname()).append("：").append(y.getCostPrice()).append("，");
                    seatNamesSalePrice.append(y.getSeatname()).append("：").append(y.getSalePrice()).append("，");
                    seatNamesSupplyPrice.append(y.getSeatname()).append("：").append(y.getSupplyPrice()).append("，");
                }
                if(EmptyUtils.isNotEmpty(seatNames) && seatNames.length()>1){
                    seatNames.deleteCharAt(seatNames.length()-1);
                    x.setSeatNames(seatNames.toString());
                }
                if(EmptyUtils.isNotEmpty(seatNamesCostPrice) && seatNamesCostPrice.length()>1){
                    seatNamesCostPrice.deleteCharAt(seatNamesCostPrice.length()-1);
                    x.setSeatNamesCostPrice(seatNamesCostPrice.toString());
                }
                if(EmptyUtils.isNotEmpty(seatNamesSalePrice) && seatNamesSalePrice.length()>1){
                    seatNamesSalePrice.deleteCharAt(seatNamesSalePrice.length()-1);
                    x.setSeatNamesSalePrice(seatNamesSalePrice.toString());
                }
                if(EmptyUtils.isNotEmpty(seatNamesSupplyPrice) && seatNamesSupplyPrice.length()>1){
                    seatNamesSupplyPrice.deleteCharAt(seatNamesSupplyPrice.length()-1);
                    x.setSeatNamesSupplyPrice(seatNamesSupplyPrice.toString());
                }
                x.setCostTotalAmount(costTotalAmount);
                x.setSaleTotalAmount(saleTotalAmount);
                x.setSupplyTotalAmount(saleTotalAmount);
                x.setDetailList(detailList);

                x.setCardCustomers("-");
                x.setCardSalesName("-");
                x.setBatchNumber("-");
                x.setCardNo("-");
                if(EmptyUtils.isNotEmpty(x.getCardSecretId())){
                    //如果是卡支付
                    WelfareUserCardSecretVo welfareCardSecret = welfareCardSecretService.getUserCardBindInfo(x.getCardSecretId());
                    if(EmptyUtils.isNotEmpty(welfareCardSecret)){
                        x.setCardNo(welfareCardSecret.getNumber());
                        x.setBatchNumber(welfareCardSecret.getCardBatchNumber());
                        x.setCardNo(welfareCardSecret.getNumber());
                        if(EmptyUtils.isNotEmpty(welfareCardSecret.getFeeOrderId())){
                            WelfareFeeSalesCustomersNameVo salesCustomersNameVo = welfareFeeOrderService.selectSalesCustomersNameVoByFeeOrderId(welfareCardSecret.getFeeOrderId());
                            if(EmptyUtils.isNotEmpty(salesCustomersNameVo)){
                                x.setCardCustomers(salesCustomersNameVo.getCustomersName());
                                x.setCardSalesName(salesCustomersNameVo.getSalesName());
                            }
                        }
                    }
                }
            }
        }
        return list;
    }

    @Override
    public PageInfo<WelfareMovieOrderListVo> getMovieOrderVoPage(WelfareMovieOrderListQuery query) {
        PageHelper.startPage(query);
        List<WelfareMovieOrderListVo> list = getMovieOrderVoList(query);
        PageInfo<WelfareMovieOrderListVo> page = new PageInfo<WelfareMovieOrderListVo>(list);
        return page;
    }

    @Override
    public WelfareMovieOrderInfoVo getMovieOrderById(Integer id) {
        WelfareMovieOrderInfoVo welfareMovieOrderInfoVo = mapper.getMovieOrderById(id);
        if (EmptyUtils.isNotEmpty(welfareMovieOrderInfoVo)){
            welfareMovieOrderInfoVo.setOrderTypeName("电影订单");
            welfareMovieOrderInfoVo.setSupplierName("嘟电影");
            welfareMovieOrderInfoVo.setPartitionName("电影专区");
            Integer orderId = welfareMovieOrderInfoVo.getId();
            Example detailExp = new Example(WelfareMovieOrderDetail.class);
            detailExp.createCriteria().andEqualTo("orderId", orderId);
            BigDecimal originalAmount = new BigDecimal(welfareMovieOrderInfoVo.getOriginalamount());
            BigDecimal profitAmount = welfareMovieOrderInfoVo.getOrderTotalAmount().subtract(originalAmount);
            BigDecimal profitRateBigDecimal = profitAmount.divide(originalAmount, 4, BigDecimal.ROUND_HALF_UP);
            String profitRate = profitRateBigDecimal.multiply(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_HALF_UP).toString() + "%";
            welfareMovieOrderInfoVo.setProfitRate(profitRate);
            List<WelfareMovieOrderDetail> detailList =  welfareMovieOrderDetailService.selectByExample(detailExp);
            StringBuilder seatNames = new StringBuilder();
            BigDecimal costTotalAmount = BigDecimal.ZERO;
            BigDecimal saleTotalAmount = BigDecimal.ZERO;
            for(WelfareMovieOrderDetail y : detailList) {
                seatNames.append(y.getSeatname()).append("、");
                costTotalAmount = costTotalAmount.add(y.getCostPrice());
                saleTotalAmount = saleTotalAmount.add(y.getSalePrice());
            }
            if(EmptyUtils.isEmpty(welfareMovieOrderInfoVo.getUpdaterName())){
                welfareMovieOrderInfoVo.setUpdaterName("");
            }
            if(EmptyUtils.isEmpty(welfareMovieOrderInfoVo.getRemark())){
                welfareMovieOrderInfoVo.setRemark("");
            }
            if(EmptyUtils.isNotEmpty(seatNames) && seatNames.length()>1){
                seatNames.deleteCharAt(seatNames.length()-1);
                welfareMovieOrderInfoVo.setSeatNames(seatNames.toString());
            }
            welfareMovieOrderInfoVo.setCostTotalAmount(costTotalAmount);
            welfareMovieOrderInfoVo.setSaleTotalAmount(saleTotalAmount);
            welfareMovieOrderInfoVo.setDetailList(detailList);
        }
        return welfareMovieOrderInfoVo;
    }

    @Master
    @Override
    public Integer updateRefundOrderForMovie(WelfareMovieOrderRefundDto dto) {
        String refundNo = String.valueOf(System.currentTimeMillis());
        //是否发送退款短信短信 0不发，1发
        int isSendMsg;
        //锁住
        String key = RedisUtil.ORDER_REFUND_LOCK_PREFIX + dto.getOrderId();
        RLock rLock = RedisUtil.lock(key);
        try {
            if (rLock.tryLock(15, TimeUnit.SECONDS)) {
                // 查询当前订单
                WelfareMovieOrder welfareMovieOrder = mapper.selectByPrimaryKey(dto.getOrderId());
                if (!welfareMovieOrder.getPlatformStatus().equals(1)) {
                    throw new CommonException("该订单状态无法退款！");
                }
                //退款金额
                BigDecimal refundAmount = welfareMovieOrder.getPaymentAmount();
                //退款积分
                BigDecimal refundPoints = welfareMovieOrder.getCreditsAmount();
                if (welfareMovieOrder.getEnterpriseId().equals(0)) {
                    isSendMsg = 1; //发送退款短信
                    //为0 福利兔 兔福宝 是卡支付
                    //查询订单各卡支付信息
                    if (EmptyUtils.isNotEmpty(welfareMovieOrder.getCardSecretId())){
                        Integer cardSecretId = welfareMovieOrder.getCardSecretId();
                        BigDecimal cardPayAmount = welfareMovieOrder.getCreditsAmount();
                        //如果有卡密id就说明这笔订单有卡参与支付
                        if (EmptyUtils.isNotEmpty(cardSecretId)) {
                            //通过卡密id找到这张卡
                            WelfareCardSecret welfareCardSecret = welfareCardSecretService.selectByPrimaryKey(cardSecretId);
                            if (EmptyUtils.isEmpty(welfareCardSecret)) {
                                throw new CommonException("该卡数据已丢失！");
                            }
                            BigDecimal totalAmount = welfareCardSecret.getTotalAmount();
                            BigDecimal usedAmount = welfareCardSecret.getUsedAmount();
                            BigDecimal remainAmount = welfareCardSecret.getRemainAmount();
                            BigDecimal putInAmount = welfareCardSecret.getPutInAmount();
                            BigDecimal putOutAmount = welfareCardSecret.getPutOutAmount();
                            usedAmount = usedAmount.subtract(cardPayAmount);
                            remainAmount = remainAmount.add(cardPayAmount);
                            if ((usedAmount.add(remainAmount).subtract(putInAmount).add(putOutAmount)).compareTo(totalAmount) != 0) {
                                throw new CommonException("退款后积分总额对不上，无法进行退款！");
                            }
                            if (usedAmount.compareTo(BigDecimal.ZERO) < 0) {
                                throw new CommonException("退款后已用积分变为负数，测试脏数据有误，无法退款！");
                            }
                            welfareCardSecret.setUpdater(dto.getUpdater());
                            welfareCardSecret.setUpdateTime(new Date());
                            welfareCardSecret.setUsedAmount(usedAmount);
                            welfareCardSecret.setRemainAmount(remainAmount);
                            welfareCardSecretService.updateByPrimaryKeySelective(welfareCardSecret);
                        }
                    }
                } else {
                    isSendMsg = 0; //不发退款短信
                    //否则是积分支付
                    WelfareUserWx welfareUserWx = welfareUserWxService.selectByPrimaryKey(welfareMovieOrder.getUserId());
                    WelfareUserWx newUserWx = new WelfareUserWx();
                    newUserWx.setId(welfareUserWx.getId());
                    newUserWx.setBalanceIntegral(welfareUserWx.getBalanceIntegral().add(welfareMovieOrder.getCreditsAmount())); //退积分余额
                    newUserWx.setConsumeIntegral(welfareUserWx.getConsumeIntegral().subtract(welfareMovieOrder.getCreditsAmount())); //扣已使用积分
                    if ((newUserWx.getBalanceIntegral().add(newUserWx.getConsumeIntegral()).add(welfareUserWx.getExpiredIntegral())).compareTo(welfareUserWx.getTotalIntegral()) != 0) {
                        //退款后 积分余额+已用积分不等于总积分
                        throw new CommonException("退款后积分总额对不上，无法进行退款！");
                    }
                    welfareUserWxService.updateByPrimaryKeySelective(newUserWx);
                    //给用户退积分也要写入积分详情表
                    WelfareIntegralGrantDetail integralGrantDetail = new WelfareIntegralGrantDetail();
                    integralGrantDetail.setType(4);
                    integralGrantDetail.setCreateTime(new Date());
                    integralGrantDetail.setUserId(welfareUserWx.getId());
                    integralGrantDetail.setGrantIntegral(welfareMovieOrder.getCreditsAmount());
                    welfareIntegralGrantDetailService.insertSelective(integralGrantDetail);
                }
                //退款人民币
                try {
                    // 微信退还订单金额
                    //退款金额
                    BigDecimal returnPrice = WXPayUtil.calcWxPayPrice(welfareMovieOrder.getPaymentAmount());
                    if (returnPrice.compareTo(BigDecimal.ZERO) > 0) {
                        if (returnPrice.compareTo(returnPrice) < 0) {
                            String errLog = "微信退款失败, 退款金额不能大于实际支付金额, 请检查订单是否为测试订单";
                            log.error(errLog);
                            operationLogService.saveOrderReturnFail(dto.getOrderId(), errLog);
                            throw new CommonException("微信退款失败, 退款金额不能大于实际支付金额, 请检查订单是否为测试订单");
                        } else {
                            WelfareEnterprise welfareEnterprise = welfareEnterpriseService.selectByPrimaryKey(welfareMovieOrder.getEnterpriseId());
                            if(EmptyUtils.isEmpty(welfareEnterprise) || EmptyUtils.isEmpty(welfareEnterprise.getAppid()) || EmptyUtils.isEmpty(welfareEnterprise.getAppsecret())
                                    || EmptyUtils.isEmpty(welfareEnterprise.getMchId()) || EmptyUtils.isEmpty(welfareEnterprise.getMchKey())){
                                throw new CommonException("微信退款失败:缺少小程序独立部署配置参数");
                            }
                            String xml = WXPayUtil.generateRefundSignature(welfareEnterprise.getAppid(), welfareEnterprise.getMchId(), welfareEnterprise.getMchKey(), returnPrice, returnPrice, welfareMovieOrder.getOutTradeNo(), refundNo);
                            String wxResponse = HttpRequest.doCertificatePost(welfareEnterprise.getMchId(), WxConfig.REFUND_URL, xml, WxConfig.getXcxCertPath());
                            //String xml = WXPayUtil.generateRefundSignature(WxConfig.WX_XCX_APPID, WxConfig.WX_PARTNER, WxConfig.WX_PARTNER_KEY, returnPrice, returnPrice, welfareMovieOrder.getOutTradeNo(), refundNo);
                            //String wxResponse = HttpRequest.doCertificatePost(WxConfig.WX_PARTNER, WxConfig.REFUND_URL, xml, WxConfig.getXcxCertPath());
                            Map<String, String> resultMap = WXPayUtil.readStringXmlOut(wxResponse);
                            if (!WXPayConstants.SUCCESS.equalsIgnoreCase(resultMap.get("return_code"))) {
                                String errLog = "微信退款失败 , 原因" + resultMap.get("return_msg") + " wxResponse :{" + wxResponse + "}";
                                log.error(errLog);
                                operationLogService.saveOrderReturnFail(dto.getOrderId(), errLog);
                                throw new CommonException("微信退款失败");
                            } else if (!WXPayConstants.SUCCESS.equalsIgnoreCase(resultMap.get("result_code"))) {
                                String errLog = "微信退款失败 , 原因" + resultMap.get("err_code_des") + " wxResponse :{" + wxResponse + "}";
                                log.error(errLog);
                                operationLogService.saveOrderReturnFail(dto.getOrderId(), errLog);
                                throw new CommonException("微信退款失败");
                            } else {
                                String log = "微信退款成功, 退款金额[" + returnPrice + "], 退款单号" + welfareMovieOrder.getTradeno();
                                operationLogService.saveOrderReturnSuccess(dto.getOrderId(), log);
                            }
                        }
                    }
                } catch (Exception e) {
                    operationLogService.saveOrderReturnFail(dto.getOrderId(), "微信退款异常, 原因:" + e.getMessage());
                    throw new CommonException(e.getMessage());
                }
                //更新订单状态为已退款
                WelfareMovieOrder welfareMovieOrderUpd = new WelfareMovieOrder();
                welfareMovieOrderUpd.setId(dto.getOrderId());
                welfareMovieOrderUpd.setUpdateTime(new Date());
                welfareMovieOrderUpd.setUpdaterName(dto.getUpdaterName());
                welfareMovieOrderUpd.setPlatformStatus(2);
                welfareMovieOrderUpd.setRemark(dto.getRefundReason());
                welfareMovieOrderUpd.setRefundTime(new Date());
                welfareMovieOrderUpd.setRefundNo(refundNo);//退款商户订单号
                if (isSendMsg == 1) {
                    String userPhone = welfareMovieOrder.getMobile();
                    //发送短信
                    SendMsgDto sendMsgDto = new SendMsgDto();
                    sendMsgDto.setOrderNo(welfareMovieOrder.getTradeno());
                    sendMsgDto.setPhone(userPhone);
                    sendMsgDto.setType("2");
                    managerService.sendMsg(sendMsgDto);
                }
                return mapper.updateByPrimaryKeySelective(welfareMovieOrderUpd);
            }
        } catch (Exception e) {
            throw new CommonException(e.getMessage());
        } finally {
            if (rLock.isHeldByCurrentThread()) {
                rLock.unlock();
            }
        }
        return null;
    }
}